package com.yun.zhong.fu.sharecenter.spring_origiond_code_study;

import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * @Author RenPu
 * @Date 2022/10/23 9:47
 * @Version 1.0
 * @Description: spring 源码学习测试类的编写
 **/
public class StudyBeanFactroy extends ClassPathXmlApplicationContext {


    public StudyBeanFactroy(String ... configlocations){
        super(configlocations);
    }

    /**
     * spring 源码核心主干分析
     * AbstractApplicationContext中refresh()方法
     * prepareRefresh(); 初始化上下文
     * ConfigurableListableBeanFactory beanFactory = obtainFreshBeanFactory();
     *
     */



    /**
     * 空实现，是留给子类进行去实现得
     * 目的是在初始化上下文中，解析各种${}参数占位符
     */
    @Override
    protected void initPropertySources() {
        System.out.println("重写===initPropertySources===方法");
        /**
         * 使用案例场景：我们在系统属性中添加：key:username,value:wangwu,当xml中包含${username}
         * spring就会拿着这个值替换占位符
         */
        getEnvironment().getSystemProperties().put("username","wangwu");

        /**
         * this.getEnvironment().validateRequiredProperties(); 源码中此代码就是为了检查，
         * spring默认得必须配置是否缺失，如果缺失则抛出MissingRequiredPropertiesException extends IllegalStateException
         * 使用案例场景: 当setRequiredProperties设置为JAVA_HOM时，spring初始化上下文时就会检查是否配置了JAVA_HOME对应得值，如果没有就会抛出异常
         */
         getEnvironment().setRequiredProperties("JAVA_HOME");

    }


    /**
     * 工厂后置处理方法，案例使用场景：在bean得实例化，修改bean得属性信息
     * 1：将xml封装为Resource在设置字符集，编码为Encoder对象，解析xml标签为Document对象然后封装到BeanDefinition,将BeanDefinition注册到spring容器中，此过程可以称为初始化
     * 2：触发bean实例化得代表，就是直接调用spring得容器得getBean方法
     * @param beanFactory
     */
    @Override
    protected void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) {
        System.out.println("重写================postProcessBeanFactory========方法");

         BeanDefinition student = beanFactory.getBeanDefinition("student");
         student.setScope(BeanDefinition.SCOPE_PROTOTYPE);   //修改BeanDefinition属性为非单例


    }
}
